package com.cxy.config;

import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * @Description
 * @Author cxy
 * @Remark
 * @Version 1.0
 **/

@Configuration
@Slf4j
public class InterceptorConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 根据路由划分模块，不同模块不同鉴权
        registry.addInterceptor(new SaInterceptor(handler -> {

            // 登录校验 -- 拦截所有路由，并排除/user/doLogin 用于开放登录
            //            SaRouter.match("/**", "/user/doLogin", r -> StpUtil.checkLogin());
            SaRouter.match("/**")
                    .notMatch("/user/doLogin", "/acc/doLogin")
                    .check(r -> StpUtil.checkLogin());
            SaRouter.match("/acc/tokenInfo", r -> StpUtil.checkPermission("user.add"));

            // 角色校验 -- 拦截以 admin 开头的路由，必须具备 admin 角色或者 super-admin 角色才可以通过认证
            SaRouter.match("/admin/**", r -> StpUtil.checkRoleOr("admin", "super-admin"));

            // 权限校验 -- 不同模块校验不同权限
            SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
            SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
            SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
            SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
            SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
            SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));

            // 甚至你可以随意的写一个打印语句
            SaRouter.match("/**", r -> System.out.println("----啦啦啦----"));

            // 连缀写法
            SaRouter.match("/**").check(r -> System.out.println("----啦啦啦----"));

            // 更多模块...
        })).addPathPatterns("/**");
    }


    //    /**
    //     * 匹配特征详解
    //     * 除了上述示例的 path 路由匹配，还可以根据很多其它特征进行匹配，以下是所有可匹配的特征：
    //     *
    //     * @param registry
    //     */
    //    @Override
    //    public void addInterceptors(InterceptorRegistry registry) {
    //        // 根据路由划分模块，不同模块不同鉴权
    //        registry.addInterceptor(new SaInterceptor(handler -> {
    //            // 基础写法样例：匹配一个path，执行一个校验函数
    //            SaRouter.match("/user/**").check(r -> StpUtil.checkLogin());
    //
    //            // 根据 path 路由匹配   ——— 支持写多个path，支持写 restful 风格路由
    //            // 功能说明: 使用 /user , /goods 或者 /art/get 开头的任意路由都将进入 check 方法
    //            SaRouter.match("/user/**", "/goods/**", "/art/get/{id}").check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 根据 path 路由排除匹配
    //            // 功能说明: 使用 .html , .css 或者 .js 结尾的任意路由都将跳过, 不会进入 check 方法
    //            SaRouter.match("/**").notMatch("*.html", "*.css", "*.js").check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 根据请求类型匹配
    //            SaRouter.match(SaHttpMethod.GET).check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 根据一个 boolean 条件进行匹配
    //            SaRouter.match(StpUtil.isLogin()).check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 根据一个返回 boolean 结果的lambda表达式匹配
    //            SaRouter.match(r -> StpUtil.isLogin()).check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 多个条件一起使用
    //            // 功能说明: 必须是 Get 请求 并且 请求路径以 `/user/` 开头
    //            SaRouter.match(SaHttpMethod.GET).match("/user/**").check(r-> System.out.println("要执行的校验函数"));
    //
    //            // 可以无限连缀下去
    //            // 功能说明: 同时满足 Get 方式请求, 且路由以 /admin 开头, 路由中间带有 /send/ 字符串, 路由结尾不能是 .js 和 .css
    //            SaRouter
    //                    .match(SaHttpMethod.GET)
    //                    .match("/admin/**")
    //                    .match("/**/send/**")
    //                    .notMatch("/**/*.js")
    //                    .notMatch("/**/*.css")
    //                    // ....
    //                    .check((r -> System.out.println("只有上述所有条件都匹配成功，才会执行最后的check校验函数")));
    //
    //        })).addPathPatterns("/**");
    //    }


    //    /**
    //     * 提前退出匹配链
    //     * 使用 SaRouter.stop() 可以提前退出匹配链，例：
    //     */
    //    @Override
    //    public void addInterceptors(InterceptorRegistry registry) {
    //        // 根据路由划分模块，不同模块不同鉴权
    //        registry.addInterceptor(new SaInterceptor(handler -> {
    //            SaRouter.match("/**").check(r -> System.out.println("进入1"));
    //            SaRouter.match("/**").check(r -> System.out.println("进入2")).stop();
    //            SaRouter.match("/**").check(r -> System.out.println("进入3"));
    //            SaRouter.match("/**").check(r -> System.out.println("进入4"));
    //            SaRouter.match("/**").check(r -> System.out.println("进入5"));
    //
    //            // 执行back函数后将停止匹配，也不会进入Controller，而是直接将 back参数 作为返回值输出到前端
    //            SaRouter.match("/user/back").back("要返回到前端的内容");
    //            //stop() 与 back() 函数的区别在于：
    //            //
    //            //SaRouter.stop() 会停止匹配，进入Controller。
    //            //SaRouter.back() 会停止匹配，直接返回结果到前端。
    //
    //        })).addPathPatterns("/**");
    //    }

    //    /**
    //     * 7、关闭注解校验
    //     * SaInterceptor 只要注册到项目中，默认就会打开注解校验，如果要关闭此能力，需要：
    //     */
    //    @Override
    //    public void addInterceptors(InterceptorRegistry registry) {
    //        registry.addInterceptor(
    //                new SaInterceptor(handle -> {
    //                    SaRouter.match("/**").check(r -> StpUtil.checkLogin());
    //                }).isAnnotation(false)  // 指定关闭掉注解鉴权能力，这样框架就只会做路由拦截校验了
    //        ).addPathPatterns("/**");
    //    }


}
